/**
 * @description React wangEditor usage
 * @author wangfupeng
 */

import React, {useState, useEffect} from 'react'
import '@wangeditor/editor/dist/css/style.css'
import {Editor, Toolbar} from '@wangeditor/editor-for-react'

function MyEditor2() {
    const [editor, setEditor] = useState(null) // 存储 editor 实例
    const [html, setHtml] = useState('<p>hello</p>')

    // 模拟 ajax 请求，异步设置 html
    useEffect(() => {
        setTimeout(() => {
            setHtml('<p>hello&nbsp;<strong>world</strong>.</p>\n<p><br></p>')
        }, 1500)
    }, [])

    const toolbarConfig = {}
    const editorConfig = {
        placeholder: '请输入内容...',
        MENU_CONF: {}
    }
    editorConfig.MENU_CONF['uploadImage'] = {
        // form-data fieldName ，默认值 'wangeditor-uploaded-image'
        fieldName: 'your-custom-name',

        // 单个文件的最大体积限制，默认为 2M
        maxFileSize: 1 * 1024 * 1024, // 1M

        // 最多可上传几个文件，默认为 100
        maxNumberOfFiles: 10,

        // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
        allowedFileTypes: ['image/*'],

        // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
        meta: {
            token: 'xxx',
            otherKey: 'yyy'
        },

        // 将 meta 拼接到 url 参数中，默认 false
        metaWithUrl: false,

        // 自定义增加 http  header
        headers: {
            Accept: 'text/x-json',
            otherKey: 'xxx'
        },

        // 跨域是否传递 cookie ，默认为 false
        withCredentials: true,

        // 超时时间，默认为 10 秒
        timeout: 5 * 1000, // 5 秒
        // 上传之前触发
        // onBeforeUpload(file: File) { // TS 语法
        onBeforeUpload(file) {    // JS 语法
            // file 选中的文件，格式如 { key: file }
            return file

            // 可以 return
            // 1. return file 或者 new 一个 file ，接下来将上传
            // 2. return false ，不上传这个 file
        },

        // 上传进度的回调函数
        // onProgress(progress: number) {  // TS 语法
        onProgress(progress) {       // JS 语法
            // progress 是 0-100 的数字
            console.log('progress', progress)
        },

        // 单个文件上传成功之后
        // onSuccess(file: File, res: any) {  // TS 语法
        onSuccess(file, res) {          // JS 语法
            console.log(`${file.name} 上传成功`, res)
        },

        // 单个文件上传失败
        // onFailed(file: File, res: any) {   // TS 语法
        onFailed(file, res) {           // JS 语法
            console.log(`${file.name} 上传失败`, res)
        },

        // 上传错误，或者触发 timeout 超时
        // onError(file: File, err: any, res: any) {  // TS 语法
        onError(file, err, res) {               // JS 语法
            console.log(`${file.name} 上传出错`, err, res)
        },
        // 自定义上传
        // async customUpload(file: File, insertFn: InsertFnType) {  // TS 语法
        async customUpload(file, insertFn) {                   // JS 语法
            // file 即选中的文件
            // 自己实现上传，并得到图片 url alt href
            // 最后插入图片
            // insertFn(url, alt, href)
            console.log(file)
        }
    }
// 插入图片
    editorConfig.MENU_CONF['insertImage'] = {
        // onInsertedImage(imageNode: ImageElement | null) {  // TS 语法
        onInsertedImage(imageNode) {                    // JS 语法
            if (imageNode == null) return

            const {src, alt, url, href} = imageNode
            console.log('inserted image', src, alt, url, href)
        },
        checkImage: customCheckImageFn, // 也支持 async 函数
        parseImageSrc: customParseImageSrc, // 也支持 async 函数
    }
// 编辑图片
    editorConfig.MENU_CONF['editImage'] = {
        // onUpdatedImage(imageNode: ImageElement | null) {  // TS 语法
        onUpdatedImage(imageNode) {                    // JS 语法
            if (imageNode == null) return

            const {src, alt, url} = imageNode
            console.log('updated image', src, alt, url)
        },
        checkImage: customCheckImageFn, // 也支持 async 函数
        parseImageSrc: customParseImageSrc, // 也支持 async 函数
    }

    // 及时销毁 editor
    useEffect(() => {
        return () => {
            if (editor == null) return
            editor.destroy()
            setEditor(null)
        }
    }, [editor])

    function insertText() {
        if (editor == null) return
        editor.insertText(' hello ')
    }

    function printHtml() {
        if (editor == null) return
        console.log(editor.getHtml())
    }

// 自定义校验图片
//     function customCheckImageFn(src: string, alt: string, url: string): boolean | undefined | string { // TS 语法
    function customCheckImageFn(src, alt, url) {                                                    // JS 语法
        if (!src) {
            return
        }
        if (src.indexOf('http') !== 0) {
            return '图片网址必须以 http/https 开头'
        }
        return true

        // 返回值有三种选择：
        // 1. 返回 true ，说明检查通过，编辑器将正常插入图片
        // 2. 返回一个字符串，说明检查未通过，编辑器会阻止插入。会 alert 出错误信息（即返回的字符串）
        // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止插入。但不会提示任何信息
    }

// 转换图片链接
//     function customParseImageSrc(src: string): string {  // TS 语法
    function customParseImageSrc(src) {               // JS 语法
        if (src.indexOf('http') !== 0) {
            return `http://${src}`
        }
        return src
    }

    return (
        <>
            <div>
                <button onClick={insertText}>insert text</button>
                <button onClick={printHtml}>print html</button>
            </div>

            <div style={{border: '1px solid #ccc', zIndex: 100, marginTop: '15px'}}>
                <Toolbar
                    editor={editor}
                    defaultConfig={toolbarConfig}
                    mode="default"
                    style={{borderBottom: '1px solid #ccc'}}
                />
                <Editor
                    defaultConfig={editorConfig}
                    value={html}
                    onCreated={setEditor}
                    onChange={editor => setHtml(editor.getHtml())}
                    mode="default"
                    style={{height: '500px'}}
                />
            </div>
            <div style={{marginTop: '15px'}}>
                {html}
            </div>
        </>
    )
}

export default MyEditor2